package ginresult

import (
	"fmt"
	"net/http"
)

/**
通用业务代码
*/
const  (
	C_ERROR = -1 // 通用错误，只是代表有错，没有具体的意义
	C_SUCCESS = 0 // 通用成功，只是代表成功，没有具体的意义
	C_S_OK = 20000
	C_E_BADREQUEST = 40000
	C_E_FORBIDDEN = 40300 //没有权限
	C_E_SERVER=50000

)



/**
出现错误，Panic,自动由中间件recover，并c.JSON回
 */
type PreErrorResult struct {
	data interface{}
	err error
}

//最多支持带两个参数
//多了也没有意义，
//只是为了执行如下代码：
//result.NewErrorResult(context.BindJSON(user)).Unwrap()
//成功后Unwrap直接返回结果
//有错误由错误中间件处理
//2021-07-19，一直想由调用者指定http status code 及业务错误代码
//
func NewPreErrorResult(in ...interface{}) *PreErrorResult {
	//参数情况
	paramlen := len(in)
	//0,没有参数
	//1，一个参数
	//2 两个参数
	//0,没有参数，肯定不会有错，返回空
	if paramlen == 0 {
		return &PreErrorResult{}
	} else if paramlen == 1{//
		//参数是1的情况，看是不是error
		if in[0]==nil{
			return &PreErrorResult{}
		}
		if err,ok := in[0].(error);ok {
			return &PreErrorResult{
				err: err,
				data: nil,
			}
		} else {
			return &PreErrorResult{
				err: nil,
				data: in[0],
			}
		}

	} else if paramlen == 2 {
		//参数是两个的情况
		errIndex := -1
		nilIndex := -1
		dataIndex := 0
		var err error = nil
		var ok = false
		for key, value := range in {
			if value==nil{
				nilIndex = key
			}
			if err, ok = value.(error); ok {
				errIndex = key
				break
			}
		}
		//1.没有找到error的情况,

		if errIndex == -1 || nilIndex >=0 {
			//没有error或error为nil
			return &PreErrorResult{
				err:  nil,
				data: in[dataIndex^(1-nilIndex)],
			}
		} else if errIndex >= 0 {
			return &PreErrorResult{
				err:  err,
				data: in[dataIndex^(1-errIndex)],
			}
		} else {
			return &PreErrorResult{
				err:  nil,
				data: in[dataIndex],
			}
		}
	} else { //参数不是0,1,2 直接报错
		err:=fmt.Errorf("服务器内部Error处理流程NewErrorResult传入参数错误:" +
			"允许的参数个数<=2,实际输入的参数个数为%d,请用多条语句调用需要错误处理的程序段",paramlen)
		custom_err := NewErrorCustom(http.StatusInternalServerError,
			50000,
			err)
		panic(custom_err)
	}

}


func (e *PreErrorResult)Unwrap() interface{}  {
	if e.err!=nil{
		customErr := NewErrorCustom(http.StatusBadRequest,40000,e.err)
		panic(customErr)
		//panic(e.err.Error())
	}
	return e.data
}

//指定错误码
func (e *PreErrorResult)UnwrapWithErrorCode(httpCode,businessCode int) interface{}  {
	if e.err!=nil{
		customErr := NewErrorCustom(httpCode,businessCode,e.err)
		panic(customErr)
	}
	return e.data
}